﻿using HappyTravelling.Adapter.Google;
using MoneyLover.Constant;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Device.Location;
using System.Net;
using System.Threading.Tasks;

namespace HappyTravelling.Service
{
    public static class GoogleMapsService
    {
        public const string Map_Search_Query = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location={0},{1}&types={3}&sensor=true&keyword={4}&key={2}&rankby=distance";
        //"https://maps.googleapis.com/maps/api/place/search/json?location={0},{1}&radius={3}&types={4}&sensor=true&keyword={5}&key={2}";

        public static int Map_Search_Radius = 5000;

        public static async Task<List<PlaceItem>> SearchPlace(string keyword, double lat, double longt)
        {
            var wc = new WebClient();
            var r = await wc.DownloadStringTaskAsync(string.Format(Map_Search_Query,
                                                                   lat,
                                                                   longt,
                                                                   Config.Google_Place_API,
                                                                   "",
                                                                   keyword));
            return ParsePlaceItem(r);
        }

        public static async Task<List<PlaceItem>> SearchPlace(string keyword, GeoCoordinate coo)
        {
            return await SearchPlace(keyword, coo.Latitude, coo.Longitude);
        }

        public static async Task<List<PlaceItem>> GetAtmLocation(double lat, double longt)
        {
            var wc = new WebClient();
            var r = await wc.DownloadStringTaskAsync(string.Format(Map_Search_Query,
                                                                   lat,
                                                                   longt,
                                                                   Config.Google_Place_API,
                                                                   "atm",
                                                                   "atm"));
            return ParsePlaceItem(r);
        }

        public static async Task<List<PlaceItem>> GetAtmLocation(GeoCoordinate coo)
        {
            return await GetAtmLocation(coo.Latitude, coo.Longitude);
        }

        public static async Task<List<PlaceItem>> GetBankLocation(double lat, double longt)
        {
            var wc = new WebClient();
            var r = await wc.DownloadStringTaskAsync(string.Format(Map_Search_Query,
                                                                   lat,
                                                                   longt,
                                                                   Config.Google_Place_API,
                                                                   "bank",
                                                                   "bank"));
            return ParsePlaceItem(r);
        }

        public static async Task<List<PlaceItem>> GetBankLocation(GeoCoordinate coo)
        {
            return await GetBankLocation(coo.Latitude, coo.Longitude);
        }

        private static List<PlaceItem> ParsePlaceItem(string r)
        {
            var jo = JObject.Parse(r);
            var list = new List<PlaceItem>();
            int count = 0;
            foreach (JObject item in (JArray)jo["results"])
            {
                count++;
                try
                {
                    list.Add(new PlaceItem
                    {
                        ID = count,
                        latitude = (double)item["geometry"]["location"]["lat"],
                        longitude = (double)item["geometry"]["location"]["lng"],
                        reference = (string)item["reference"],
                        Name = (string)item["name"],
                        Address = (string)item["vicinity"]
                    });
                }
                catch { }
            }
            return list;
        }

    }

    public enum GoogleTileTypes
    {
        Hybrid,
        Physical,
        Street,
        Satellite,
        WaterOverlay
    }

    public class GoogleTile : Microsoft.Phone.Controls.Maps.TileSource
    {
        private int _server;
        private char _mapmode;
        private GoogleTileTypes _tiletypes;

        public GoogleTileTypes TileTypes
        {
            get { return _tiletypes; }
            set
            {
                _tiletypes = value;
                MapMode = MapModeConverter(value);
            }
        }

        public char MapMode
        {
            get { return _mapmode; }
            set { _mapmode = value; }
        }

        public int Server
        {
            get { return _server; }
            set { _server = value; }
        }

        public GoogleTile()
        {
            UriFormat = @"http://mt{0}.google.com/vt/lyrs={1}&z={2}&x={3}&y={4}";
            Server = 0;
        }

        public override Uri GetUri(int x, int y, int zoomLevel)
        {
            if (zoomLevel > 0)
            {
                var Url = string.Format(UriFormat, Server, MapMode, zoomLevel, x, y);
                return new Uri(Url);
            }
            return null;
        }

        private char MapModeConverter(GoogleTileTypes tiletype)
        {
            switch (tiletype)
            {
                case GoogleTileTypes.Hybrid:
                    {
                        return 'y';
                    }
                case GoogleTileTypes.Physical:
                    {
                        return 't';
                    }
                case GoogleTileTypes.Satellite:
                    {
                        return 's';
                    }
                case GoogleTileTypes.Street:
                    {
                        return 'm';
                    }
                case GoogleTileTypes.WaterOverlay:
                    {
                        return 'r';
                    }
            }
            return ' ';
        }
    }
}